"""睡眠分析会话 ORM 模型

基于Peewee ORM的睡眠分析会话表映射，支持频域比例累积数据存储模式
用于实现一次会话一条记录，每次新数据更新现有记录的累积存储逻辑
"""

import json
from datetime import datetime
from typing import List, Dict, Any, Optional
from peewee import *
from app.core.database import BaseModel


class SleepAnalysisSessionORM(BaseModel):
    """睡眠分析会话 ORM 模型
    
    对应 sleep_analysis_sessions 表，支持频域比例累积数据存储模式
    实现一次会话对应一条数据库记录，每次有新数据时更新现有记录
    """
    
    # 主键和基础信息
    id = AutoField(primary_key=True, help_text="自增主键")
    session_id = CharField(max_length=100, unique=True, help_text="会话ID，业务主键")
    room_id = CharField(max_length=36, index=True, help_text="房间ID")
    user_id = CharField(max_length=50, default="default_user", help_text="用户ID")
    
    # 会话时间信息
    session_start_time = DateTimeField(default=datetime.now, help_text="会话开始时间")
    last_update_time = DateTimeField(default=datetime.now, help_text="最后更新时间")
    session_duration_seconds = IntegerField(default=0, help_text="会话总时长（秒）")
    
    # 数据统计信息
    total_data_points = IntegerField(default=0, help_text="总数据点数量")
    first_data_timestamp = FloatField(null=True, help_text="第一个数据点时间戳")
    last_data_timestamp = FloatField(null=True, help_text="最后一个数据点时间戳")
    
    # 累积数据存储 - JSON字段
    frequency_analysis_data = TextField(null=True, help_text="频域分析数据点数组，JSON格式")
    
    # 会话状态和质量指标
    session_status = CharField(max_length=20, default="active", help_text="会话状态")
    average_confidence = FloatField(default=0.0, help_text="平均分期置信度")
    dominant_sleep_state = CharField(max_length=50, default="unknown", help_text="主要睡眠分期")
    signal_quality_score = FloatField(default=0.0, help_text="信号质量评分")
    data_completeness_ratio = FloatField(default=0.0, help_text="数据完整性比例")
    
    class Meta:
        table_name = 'sleep_analysis_sessions'
        indexes = (
            (('session_id',), True),  # 唯一索引
            (('room_id', 'session_start_time'), False),  # 复合索引
        )
    
    def add_analysis_point(self, timestamp: float, state: str, confidence: float, 
                          delta: float, theta: float, alpha: float, beta: float, gamma: float) -> None:
        """添加单个分析数据点
        
        Args:
            timestamp: 数据点时间戳
            state: 睡眠分期结果
            confidence: 分期置信度
            delta: Delta波段比例
            theta: Theta波段比例
            alpha: Alpha波段比例
            beta: Beta波段比例
            gamma: Gamma波段比例
        """
        # 解析现有数据
        existing_data = []
        if self.frequency_analysis_data:
            try:
                existing_data = json.loads(self.frequency_analysis_data)
            except json.JSONDecodeError:
                existing_data = []
        
        # 创建新数据点
        new_point = {
            "timestamp": timestamp,
            "state": state,
            "confidence": confidence,
            "delta": delta,
            "theta": theta,
            "alpha": alpha,
            "beta": beta,
            "gamma": gamma
        }
        
        # 添加到数据列表
        existing_data.append(new_point)
        
        # 更新字段
        self.frequency_analysis_data = json.dumps(existing_data)
        self.total_data_points = len(existing_data)
        self.last_update_time = datetime.now()
        self.last_data_timestamp = timestamp
        
        # 更新第一个数据点时间戳
        if self.first_data_timestamp is None:
            self.first_data_timestamp = timestamp
        
        # 更新统计信息
        self._update_statistics(existing_data)
    
    def add_analysis_points(self, data_points: List[Dict[str, Any]]) -> None:
        """批量添加分析数据点
        
        Args:
            data_points: 数据点列表，每个元素包含timestamp, state, confidence, delta, theta, alpha, beta, gamma
        """
        # 解析现有数据
        existing_data = []
        if self.frequency_analysis_data:
            try:
                existing_data = json.loads(self.frequency_analysis_data)
            except json.JSONDecodeError:
                existing_data = []
        
        # 添加新数据点
        for point in data_points:
            new_point = {
                "timestamp": point["timestamp"],
                "state": point["state"],
                "confidence": point["confidence"],
                "delta": point["delta"],
                "theta": point["theta"],
                "alpha": point["alpha"],
                "beta": point["beta"],
                "gamma": point["gamma"]
            }
            existing_data.append(new_point)
        
        # 更新字段
        self.frequency_analysis_data = json.dumps(existing_data)
        self.total_data_points = len(existing_data)
        self.last_update_time = datetime.now()
        
        # 更新时间戳信息
        if data_points:
            self.last_data_timestamp = max(point["timestamp"] for point in data_points)
            if self.first_data_timestamp is None:
                self.first_data_timestamp = min(point["timestamp"] for point in data_points)
        
        # 更新统计信息
        self._update_statistics(existing_data)
    
    def _update_statistics(self, data_points: List[Dict[str, Any]]) -> None:
        """更新统计信息
        
        Args:
            data_points: 所有数据点列表
        """
        if not data_points:
            return
        
        # 计算平均置信度
        confidences = [point["confidence"] for point in data_points]
        self.average_confidence = sum(confidences) / len(confidences)
        
        # 计算主要睡眠分期
        states = [point["state"] for point in data_points]
        state_counts = {}
        for state in states:
            state_counts[state] = state_counts.get(state, 0) + 1
        self.dominant_sleep_state = max(state_counts, key=state_counts.get)
        
        # 计算会话时长
        if self.first_data_timestamp and self.last_data_timestamp:
            self.session_duration_seconds = int(self.last_data_timestamp - self.first_data_timestamp)
        
        # 简单的数据质量评估
        self.signal_quality_score = min(self.average_confidence * 1.2, 1.0)  # 基于置信度评估
        self.data_completeness_ratio = min(len(data_points) / 100.0, 1.0)  # 假设100个数据点为完整
    
    def get_analysis_data(self) -> List[Dict[str, Any]]:
        """获取分析数据点列表
        
        Returns:
            List[Dict]: 分析数据点列表
        """
        if not self.frequency_analysis_data:
            return []
        
        try:
            return json.loads(self.frequency_analysis_data)
        except json.JSONDecodeError:
            return []
    
    @classmethod
    def get_or_create_session(cls, session_id: str, room_id: str, user_id: str = "default_user") -> 'SleepAnalysisSessionORM':
        """获取或创建会话记录
        
        Args:
            session_id: 会话ID
            room_id: 房间ID
            user_id: 用户ID
            
        Returns:
            SleepAnalysisSessionORM: 会话记录实例
        """
        try:
            # 尝试获取现有记录
            return cls.get(cls.session_id == session_id)
        except cls.DoesNotExist:
            # 创建新记录
            return cls.create(
                session_id=session_id,
                room_id=room_id,
                user_id=user_id,
                session_start_time=datetime.now()
            )